package com.ruix.app.util;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * User: Ray
 * Date: 16/3/22
 * ReadMe: 线程管理类
 */
public class ThreadManager {
    private static ExecutorService singleThreadExecutor = null;
    private static ScheduledExecutorService scheduledThreadPool = null;
    private static ExecutorService fixedThreadPool = null;
    private static ExecutorService cachedThreadPool = null;
    private static ExecutorService unlimitedCachedThreadPool = null;
    private static int maxThreads = Math.max(Runtime.getRuntime().availableProcessors(), 8);

    //单线程，不会销毁
    private static synchronized ExecutorService getSingleThreadExecutor() {
        if (singleThreadExecutor == null) {
            singleThreadExecutor = Executors.newSingleThreadExecutor();
        }
        return singleThreadExecutor;
    }

    //提供轮询等
    public static synchronized ScheduledExecutorService getScheduledThreadPool() {
        if (scheduledThreadPool == null) {
            scheduledThreadPool = Executors.newSingleThreadScheduledExecutor();
        }
        return scheduledThreadPool;
    }

    //固定线程池，是单线程的扩大版。
    private static synchronized ExecutorService getFixedThreadPool() {
        if (fixedThreadPool == null) {
            fixedThreadPool = Executors.newFixedThreadPool(maxThreads);
        }
        return fixedThreadPool;
    }

    //动态生成线程，有生命周期。如下定义为60秒。60秒内没有任务就会销毁
    //队列满时丢弃前面的任务
    public static synchronized ExecutorService getCachedThreadPool() {
        if (cachedThreadPool == null) {
            cachedThreadPool = new ThreadPoolExecutor(maxThreads, maxThreads * 2,
                    60L, TimeUnit.SECONDS,
                    new LinkedBlockingQueue<Runnable>(), new ThreadPoolExecutor.DiscardOldestPolicy());
        }
        return cachedThreadPool;
    }

    //起任意个线程，尽量少用。用于不能排队的情况下。
    public static synchronized ExecutorService getUnlimitedCachedThreadPool() {
        if (unlimitedCachedThreadPool == null) {
            unlimitedCachedThreadPool = Executors.newCachedThreadPool();
        }
        return unlimitedCachedThreadPool;
    }


    /**
     * @param runnable
     * @param needQueue 单线程队列
     * @param canWait   true 需要限制线程数，如网络请求。false,不能有线程数控制，如ui方面的操作，需要立即更新操作。
     */
    public static void execute(Runnable runnable, boolean needQueue, boolean canWait) {
        if (needQueue) {
            getSingleThreadExecutor().execute(runnable);
        } else {
            if (canWait) {
                getCachedThreadPool().execute(runnable);
            } else {
                getUnlimitedCachedThreadPool().execute(runnable);
            }
        }
    }

}
